/* eslint-disable no-param-reassign */
import { setPageViewConfig } from '../lib/config';
import { pageViewItemExt, pageViewConfig, Config } from '../lib/types';
import log from '../lib/log';
import { getURLPath } from '../lib/tools';
import { clearOtherPagesCache } from '../lib/cache';

export function addPageViewListener(pageViewConf: Config) {
  function sendPageView(pageViewData: pageViewItemExt, duration: number | undefined) {
    pageViewConf.onUrlChange && pageViewConf.onUrlChange(pageViewData, pageViewConf);
    if (duration) {
      pageViewData.timeoutId = window.setTimeout(() => {
        pageViewData.timeoutId = 0;
        pageViewConf.sendPageViewData && pageViewConf.sendPageViewData(pageViewData, pageViewConf);
      }, duration);
    } else {
      pageViewConf.sendPageViewData && pageViewConf.sendPageViewData(pageViewData, pageViewConf);
    }
  }

  function pageViewDataListFilter() {
    const { pageViewData, pageViewDuration } = pageViewConf;
    if (pageViewData && Array.isArray(pageViewData)) {
      pageViewData.forEach((item: pageViewItemExt) => {
        const path: string = getURLPath();
        if (typeof item === 'object') {
          if (item.timeoutId) {
            window.clearTimeout(item.timeoutId);
          }
          if (item.path === path) {
            sendPageView(item, pageViewDuration);
          } else if (item.reg && item.reg.test(path)) {
            sendPageView(item, pageViewDuration);
          }
        } else {
          log.err('The parameter type must be an object or object[]');
        }
      });
    }
  }

  // pv上报
  function pageChange() {
    clearOtherPagesCache();
    pageViewConf.debug && log.info('Page jump: ', getURLPath());
    pageViewDataListFilter();
  }

  function historyListener(that: any, fn: Function) {
    const { history } = window;
    const { pushState, replaceState } = history;
    history.pushState = function (...args: any[]) {
      pushState.apply(history, [...args] as [any, string, (string | null | undefined)?]);
      fn.apply(that, [...args]);
    };
    history.replaceState = function (...args: any[]) {
      replaceState.apply(history, [...args] as [any, string, (string | null | undefined)?]);
      fn.apply(that, [...args]);
    };
    // 添加全局popstate事件。只有在做出浏览器动作时，才会触发该事件，
    // 如用户点击浏览器的回退按钮（或者在Javascript代码中调用history.back()或者history.forward()方法）
    window.addEventListener('popstate', pageChange);
    if (pageViewConf.debug) log.info('History change event subscription');
    pageViewDataListFilter();
  }

  const { pageViewData, debug, pageViewDuration } = pageViewConf;
  debug && log.info('Open the page: ', getURLPath());
  if (pageViewData) {
    if (pageViewData instanceof Array) {
      historyListener(this, pageChange);
    } else {
      sendPageView(pageViewData, pageViewDuration);
    }
  }
}

// 初始化fish PageView配置，开启PageView监听
export default function initPageView(options: pageViewConfig = {}) {
  const config: Config = setPageViewConfig(options);
  if (typeof window !== 'object') return;
  addPageViewListener(config);
}
